home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / hf / dsp / dsp4src / synt.asm < prev   
Encoding:
Assembly Source File  |  1994-04-01  |  7.5 KB  |  309 lines

  1.     page    132,63,1,1
  2.     opt    rc
  3.     title    'LPC Synthesis'
  4.  
  5. ;***************************************************************
  6. ;* SYNT.ASM -- 2400 bit/s LPC synthesizer module           *
  7. ;*                                   *
  8. ;* Provides excitation source and Lattice filter for speech    *
  9. ;* generation.                               *
  10. ;*                                   *
  11. ;* The overall implementation is based on application note     *
  12. ;*    Seshan, N.:                           *
  13. ;*    "A TMS320C30-based LPC Vocoder",               *
  14. ;*    Texas Instruments, 1990                    *
  15. ;*                                   *
  16. ;* Lattice filter implementation is based on Motorola sample   *
  17. ;* code and book                           *
  18. ;*    Proakis, J., G.:                       *
  19. ;*    "Digital Communications",                   *
  20. ;*    McGraw-Hill, 1983                       *
  21. ;*                                   *
  22. ;* Copyright (C) 1992 by Alef Null. All rights reserved.       *
  23. ;* Author(s): Jarkko Vuori, OH2LNS                   *
  24. ;* Modification(s):                           *
  25. ;*    30-Sep-92: added monotonic mode                *
  26. ;***************************************************************
  27.  
  28.     section LPCsyn
  29.     xdef    lpc_syn
  30.  
  31.     org    p:
  32.  
  33.     nolist
  34.     include 'macros'
  35.     include 'leonid'
  36.     list
  37.  
  38.  
  39. ; Synthesize output from LPC parameters
  40. lpc_syn move            #-1,m0
  41.     move            m0,m4
  42.  
  43.     jclr    #monot,x:<flags,_inton            ; set to constant pitch if monotonic mode
  44.     move            x:<p_s,a            ; and current frame is voiced
  45.     tst    a        #>monopit,x0
  46.     tne    x0,a
  47.     move            a1,x:<p_s
  48.  
  49. _inton    jclr    #whisper,x:<flags,_voice        ; remove voicing if in whisper mode
  50.     clr    a
  51.     move            a,x:<p_s
  52.  
  53. _voice    move            x:<p_s,a            ; test if voiced
  54.     tst    a        x:<p_d,x0
  55.     jeq    <_novc
  56.     add    x0,a        #>10,x0            ; then adjust pitch
  57.     cmp    x0,a                    ; set floor on adjustment
  58.     tlt    x0,a
  59.     move            a,x:<p_s
  60.     jmp    <_vcend
  61.  
  62. _novc    move            #>boost,x0            ; if unvoiced boost gain
  63.     move            x:<g_s,x1
  64.     mpy    x0,x1,a
  65.     lsl    a                    ; adjust fraction (fraction, integer multiplication)
  66.     asr    a
  67.     move            a0,x:<g_s
  68.  
  69. _vcend    jclr    #silence,x:<flags,_loud         ; set gain to zero if in silence mode
  70.     clr    a
  71.     move    a,x:<g_s
  72. _loud
  73.  
  74. ; Interpolate if voicing of previous frame and current frame is same
  75.     move            #-1,x0            ; first convert pitchs to logical values
  76.     move            x:<p_s,a
  77.     tst    a        x:<p_s_0,b
  78.     tne    x0,a
  79.     tst    b        a,x1
  80.     tne    x0,b
  81.  
  82.     bclr    #ipolate,x:<flags            ; then set interpolate flag if they are different
  83.     eor    x1,b
  84.     jne    <_clripo
  85.     bset    #ipolate,x:<flags
  86. _clripo
  87.  
  88. ; If interpolating initialize with last frames parameters
  89.     jclr    #ipolate,x:<flags,noipo
  90.  
  91.     move            #<k_s_0,r0            ; copy k_s_0[] to k_int[]
  92.     move            #k_int,r4
  93.     do    #P,_endip
  94.     move            x:(r0)+,a1
  95.     move            a1,x:(r4)+
  96. _endip
  97.  
  98.     move            x:<g_s_0,a1         ; g_s_0 -> g_int
  99.     move            a1,x:g_int
  100.  
  101.     jmp    <ipo
  102.  
  103. ; else reset interpolation index (exite), initialize system with
  104. ; current frame's LPC parameters and clear backward lattice state
  105. noipo    clr    a        x:<g_s,b1            ; 0   -> excite
  106.     move            a,x:excite            ; g_s -> g_int
  107.     move            b1,x:g_int
  108.  
  109.     move            #b_s,r0            ; clear b_s[]
  110.     move            r0,x:b_s_ptr
  111.     rep    #P
  112.     move            a,y:(r0)+
  113.  
  114.     move            #<k_s,r0            ; copy k_s[] to k_int[]
  115.     move            #k_int,r4
  116.     do    #P,_refcpy
  117.     move            x:(r0)+,a1
  118.     move            a1,x:(r4)+
  119. _refcpy
  120.  
  121. ; if unvoiced set interpolation interval to 1/8 frame size
  122. ipo    move            x:<p_s,a
  123.     tst    a        #>M/8,x0
  124.     jeq    <ipintv
  125.  
  126. ; else set interpolation interval to pitch. If interpolation
  127. ; is on set to last frame's pitch, otherwise set to current frame's pitch
  128. von    move            x:<p_s_0,x0         ; p_int = interpolate ? p_s_0 : p_s
  129.     jset    #ipolate,x:<flags,ipintv
  130.     move            x:<p_s,x0
  131. ipintv    move            x0,x:p_int
  132.  
  133. ;
  134.     lua            (r6)+,r0
  135.     move            #4-1,n0
  136.     move            #(3*M)*4-1,m0
  137.     do    #M,frmend
  138.     move            r0,b            ; sample index to b
  139.     move            r6,x0
  140.     sub    x0,b        #>1,x0
  141.     sub    x0,b        x:excite,a            ; check if end of interpolation interval
  142.     asr    b
  143.     asr    b
  144.     cmp    a,b
  145.     jne    <genexc
  146.  
  147. ; If interpolation flag, interpolate between previous and current frame
  148.     move            #>$03,x0
  149.     putio
  150.     wait
  151.     move            #>$01,x0
  152.     putio
  153.  
  154.     jclr    #ipolate,x:<flags,nxtipo
  155.  
  156.     move            b,x0            ; x0 = index/M, y0 = (M - index)/M
  157.     move            #1.0/@cvf(M),x1
  158.     mpy    x0,x1,a     #0.9999999,b
  159.     lsl    a                    ; adjust fraction part
  160.     asr    a
  161.     move            a0,x0
  162.     sub    x0,b        x:<p_s,a
  163.  
  164.     tst    a        b,y0            ; p_int = (i*p_s + l*p_s_0)/M
  165.     jeq    <_nopitch
  166.     move    a,x1
  167.     mpy    x0,x1,a     x:<p_s_0,y1
  168.     macr    y0,y1,a
  169.     move            a,x:p_int
  170. _nopitch
  171.  
  172.     move            #k_s,r1            ; k_int[j] = (i*k_s[j] + j*k_s_0[j])/M
  173.     move            #<k_s_0,r4
  174.     move            #k_int,r5
  175.     move            #-1,m1
  176.     move            m1,m5
  177.     do    #P,_refipo
  178.     move            x:(r1)+,x1
  179.     mpy    x0,x1,a     x:(r4)+,y1
  180.     macr    y0,y1,a
  181.     move            a,x:(r5)+
  182. _refipo
  183.  
  184.     move            x:<g_s,x1            ; g_int = (i*g_s + l*g_s_0)/M
  185.     mpy    x0,x1,a     x:<g_s_0,y1
  186.     macr    y0,y1,a
  187.     move            a,x:g_int
  188.  
  189. nxtipo    move            x:excite,a            ; set next interpolation point
  190.     move            x:p_int,x0
  191.     add    x0,a        #glottal,b1         ; reset glottal pulse pointer
  192.     move            a1,x:excite
  193.     move            b1,x:pulse
  194.  
  195. ; Generate excitation
  196. genexc    move            x:<p_s,b
  197.     tst    b        x:rand,a1
  198.     jeq    <noise
  199.  
  200. ; voiced, use 40 point DoD glottal pulse excitation
  201.     move            x:pulse,b            ; give zero if end of excitation sequence
  202.     clr    a        #>glottal+40,x0
  203.     cmp    x0,b        x:pulse,r4
  204.     jge    <genout
  205.     move            x:p_int,x0            ; pulse[]*p_int/p_max*g_int
  206.     move            #1.0/(197.0+1.0),x1
  207.     mpy    x0,x1,a     y:(r4)+,x0
  208.     move    a0,x1
  209.     mpyr    x0,x1,a     x:g_int,x0
  210.     move    a,x1
  211.     mpyr    x0,x1,a     r4,x:pulse
  212.     jmp    <genout
  213.  
  214. ; otherwise generate white noise excitation with random bit
  215. noise    lsr    a        #>poly,x0             ; generate a new random bit to C flag
  216.     jcc    <_rand
  217.     eor    x0,a
  218. _rand    move            a,x:rand
  219.  
  220.     move            x:g_int,a            ; compose excitation value
  221.     jcs    <_scale
  222.     neg    a
  223. _scale    move    a,x0                    ; scale output
  224.     move            #1.0/25.0,x1
  225.     mpyr    x0,x1,a
  226.  
  227. ; exite lattice filter and deemphasize output (excitation in a register)
  228. genout    move            #k_int+P-1,r1
  229.     move            x:b_s_ptr,r5
  230.     move            #P-1,m5
  231.     nop
  232.  
  233.     move            x:(r1)-,x0    y:(r5)+,y0  ; Lattice macro from Motorola bulletin board
  234.     macr    -x0,y0,a    x:(r1)-,x0    y:(r5)-,y0
  235.     do    #P-1,_endlat
  236.     macr    -x0,y0,a        b,y:(r5)+
  237.     move    a,x1            y:(r5)+,b
  238.     macr    x1,x0,b     x:(r1)-,x0    y:(r5)-,y0
  239. _endlat
  240.     move                b,y:(r5)+
  241.     move            x:(r1)+,x0    a,y:(r5)+
  242.     move            r5,x:b_s_ptr
  243.  
  244.     move            x:<old,x0            ; deemphasize
  245.     move            #0.9375,x1
  246.     macr    x0,x1,a
  247.     move            a,x:<old
  248.  
  249.     rep    #4                    ; scale output
  250.     asl    a
  251.  
  252.     move            a,y:(r0)+            ; output left channel
  253.     move            a,y:(r0)+n0         ; output right channel
  254. frmend
  255.  
  256.     move            x:excite,a            ; reset next excitation point for next frame
  257.     move            #>M,x0
  258.     sub    x0,a        x:<g_s,x0            ; save current values for next frame
  259.     move            a,x:excite
  260.  
  261.     move            x0,x:<g_s_0
  262.  
  263.     move            x:<p_s,x0
  264.     move            x0,x:<p_s_0
  265.  
  266.     move            #<k_s,r0
  267.     move            #-1,m0
  268.     move            #<k_s_0,r4
  269.     do    #P,_ef
  270.     move            x:(r0)+,a1
  271.     move            a1,x:(r4)+
  272. _ef
  273.  
  274.     rts
  275.  
  276.  
  277. ;****************************
  278. ;*     DATA - AREA        *
  279. ;****************************
  280.  
  281.     org    x:
  282.  
  283. k_s_0    ds    P                    ; previous reflection coefficients
  284.  
  285. g_s_0    ds    1                    ; gain for previous output frame
  286. old    dc    0                    ; previous output value
  287.  
  288. p_s_0    ds    1                    ; previous output pitch period
  289. pulse    ds    1                    ; index to glottal excitation
  290. excite    dc    0                    ; sample for next parameter interpolation
  291.  
  292. g_int    ds    1                    ; interpolated gain
  293. p_int    ds    1                    ; interpolated pitch
  294. k_int    ds    P                    ; interpolated reflection coefficients
  295.  
  296. rand    dc    $12345                    ; random number generator seed
  297.  
  298. b_s_ptr ds    1
  299.  
  300.  
  301.     org    y:
  302.  
  303.     ds    14
  304. b_s    ds    P                    ; backward lattice state
  305.  
  306.     endsec
  307.  
  308.     end
  309.